package com.ruoyi.asset.utils;

import lombok.extern.slf4j.Slf4j;

import javax.crypto.Cipher;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

/**
 * 参数加解密
 *
 * @author Liu
 * @date 2025-06-23
 */
@Slf4j
public class AesEncryptUtil {

    public static final String PADDING = " AES/CBC/PKCS5Padding";

    /**
     * 开放平台AES-256加密请求参数和返回数据
     */
    public static String aes256Encrypt(String data, String aesSecret, String aesIv) {
        try {
            Cipher cipher = Cipher.getInstance(PADDING);
            byte[] iv = java.util.Base64.getDecoder().decode(aesIv);
            SecretKey key = new
                    SecretKeySpec(java.util.Base64.getDecoder().decode(aesSecret), "AES");
            IvParameterSpec ivSpec = new IvParameterSpec(iv);
            cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
            byte[] encryptedBytes =
                    cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
            return java.util.Base64.getEncoder().encodeToString(encryptedBytes);
        } catch (Exception e) {
            log.error("AES-256加密失败", e);
            return null;
        }
    }
    /**
     * 开放平台AES-256解密请求参数和返回数据
     */
    public static String aes256Decrypt(String encryptData, String aesSecret, String aesIv) {
        try {
            Cipher cipher = Cipher.getInstance(PADDING);
            byte[] iv = java.util.Base64.getDecoder().decode(aesIv);
            SecretKey key = new
                    SecretKeySpec(java.util.Base64.getDecoder().decode(aesSecret), "AES");
            IvParameterSpec ivSpec = new IvParameterSpec(iv);
            cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
            byte[] decryptedBytes =
                    cipher.doFinal(java.util.Base64.getDecoder().decode(encryptData));
            return new String(decryptedBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            log.error("AES-256解密失败", e);
            return null;
        }
    }

    // 生成摘要签名
    public static String generateSignature(String appSecret, String data) {
        try {
            //将AppSecret作为密钥，使用HmacSHA256算法生成摘要
            Mac sha256Hmac = Mac.getInstance("HmacSHA256");
            SecretKeySpec secretKey = new
                    SecretKeySpec(appSecret.getBytes(), "HmacSHA256");
            sha256Hmac.init(secretKey);
            byte[] hmacData = sha256Hmac.doFinal(data.getBytes());
            //使用Base64编码生成签名
            return Base64.getEncoder().encodeToString(hmacData);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            log.error("生成摘要签名失败, appSecret: {}, data: {}",
                    appSecret, data, e);
        }
        return null;
    }

    public static boolean verifySignature(String appSecret, String data, String clientSignature) {
        //生成服务器端的签名
        String serverSignature = generateSignature(appSecret, data);
        //比较两个签名是否相同
        return serverSignature.equals(clientSignature);
    }
}
